﻿using STHPMS1.Common.C_Entity;
using STHPMS1.Common.C_Entity.Stmpms1;
using STHPMS1.ICore;
using STHPMS1.ICore.I_Core;
using STHPMS1.ICore.I_UI;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using STHPMS1.Common.C_Extension;
using STHPMS1.Web.W_Model;
using System.Collections.Generic;
using Newtonsoft.Json;
using STHPMS1.Common.C_Utils;
using System.Data;
using System.Reflection;
using System.Linq.Expressions;
using System.Web.Caching;
using STHPMS1.ICore.I_Serv;
using STHPMS1.ICore.I_BLL.Bus;
using STHPMS1.ICore.I_DAL;
namespace STHPMS1.Web.W_Controller.Decision.Needs
{
    [RoutePrefix("api/DiviForecast")]
    public class DiviForecastController : STHPMS1.Web.W_Core.MyController
    {
        [Route("getroadnet")]
        public IHttpActionResult GetRoadnet()
        {
            return Ok(this.Scene.Bll.B_Roadnet.Get<B_Roadnet>(null, null));
        }

        /// <summary>
        /// 循环分析养护类型
        /// </summary>
        /// <param name="rdnet">资金模型</param>
        /// <param name="y">年度</param>
        /// <returns></returns>
        [Route("forecast")]
        public IHttpActionResult PostForecast(string rdnet, int y)
        {
            ISthpms1Dao dao = this.Scene.Dal.Sthpms1;

            try
            {
                List<Dn_Divi_Planning> planList = new List<Dn_Divi_Planning>();
                if (DateTime.Now.Year == y)
                { 
                    #region 当前年份
                    //先根据路网ID，查询合适的决策路段
                    Df_Costmod_Para para = this.Scene.Bll.Df_Costmod_Para.GetCostmod_Para(rdnet) as Df_Costmod_Para;
                    B_Roadnet roadnet = this.Scene.Bll.B_Roadnet.GetSingle<B_Roadnet>(para.Roadnet_Name);//路网对象
                    IEnumerable<Dn_Divi_Result> divis = this.Scene.Bll.Dn_Divi_Result.GetResulst<Dn_Divi_Result>(roadnet);
                    if (!divis.Any())
                    {
                        throw new Exception("该路网没有合适的决策路段");
                    }
                   
                    foreach (Dn_Divi_Result r in divis)
                    {
                        //获取该决策路段的各项指标值
                        double? pci = null, pssi = null, rdi = null, rqi = null, sri = null;
                        DataRow dr = this.Scene.Bll.Dn_Divi_Result.GetTe_Data(r);
                        if (dr.IsNull(0)) //没有pci
                        {
                            //预测PCI
                            //pci =  this.Scene.Bll.Dm_Modelgroup.GetPciByModel(r, y);
                            pci =  this.Scene.Bll.Dn_Divi_Result.GetPciByModel(r, y);
                        }
                        else
                        {
                            pci = Convert.ToDouble(dr["pci"]);
                        }
                        if (dr["pssi"] != null && dr["pssi"].ToString() != "") pssi = Convert.ToDouble(dr["pssi"]);
                        if (dr["rdi"] != null && dr["rdi"].ToString() != "") rdi = Convert.ToDouble(dr["rdi"]);
                        if (dr["rqi"] != null && dr["rqi"].ToString() != "") rqi = Convert.ToDouble(dr["rqi"]);
                        if (dr["sri"] != null && dr["sri"].ToString() != "") sri = Convert.ToDouble(dr["sri"]);
                        r.Pci = pci;
                        r.Pssi = pssi;
                        r.Rdi = rdi;
                        r.Rqi = rqi;
                        r.Sri = sri;
                        //根据指标来处理养护类型
                        ProcessSEGID_MAIN(r);
                        //保存到路网决策路段表
                        Dn_Divi_Planning plan = new Dn_Divi_Planning();
                        plan.Id = Guid.NewGuid().ToString(); // id
                        plan.Anni_Name = rdnet;
                        plan.Divi_Time = y.ToString(); //规划年度
                        plan.Mainsegid = r.Mainsegid;//决策路段
                        plan.RoadnetId = rdnet;//路网ID
                        plan.Segid = r.Segid;//基础路段
                        plan.Rdwayid = r.Rdwayid;//路线编号
                        plan.Segid_Main = r.Segid_Main;//养护类型 
                        plan.Beginmp = r.Beginmp;
                        plan.Endmp = r.Endmp;
                        plan.Pqi = r.Pqi;
                        plan.Pci = r.Pci;
                        plan.Pssi = r.Pssi;
                        plan.Rqi = r.Rqi;
                        plan.Sri = r.Sri;
                        plan.Rl = r.Rl;
                        plan.Modelgroup_Pci = r.ModelGroup_PCI;//模型组ID
                        plan.Main_Year = y.ToString();//养护年份


                        //plan.Segid_Repdefl = 1;
                        //plan.Segid_Elamod = 1;
                        //plan.Segid_Pcidr = 1;
                        double Segid_Repdefl = dao.Scene.Bll.Dr_Repair_Mid.GetRepdefl(plan.Mainsegid);//计算弯沉值
                        if (Segid_Repdefl > 0)
                        {
                            plan.Segid_Repdefl = Segid_Repdefl;//计算弯沉值
                            plan.Segid_Elamod = dao.Scene.Bll.Dr_Repair_Mid.GetELAMOD(plan.Mainsegid);//回弹模量
                        }
                        else
                        {
                            plan.Segid_Repdefl = -1;
                            plan.Segid_Elamod = -1;
                        }
                        plan.Segid_Pcidr = dao.Scene.Bll.Dr_Repair_Lar.GetPCI(plan.Mainsegid);//PCI折减

                        //double Segid_Repdefl = this.Scene.Bll.Dr_Repair_Mid.GetRepdefl(plan.Mainsegid);//计算弯沉值
                        //if (Segid_Repdefl>0)
                        //{
                        //    plan.Segid_Repdefl = Segid_Repdefl;//计算弯沉值
                        //    plan.Segid_Elamod =  this.Scene.Bll.Dr_Repair_Mid.GetELAMOD(plan.Mainsegid);//回弹模量
                        //}

                        //plan.Segid_Pcidr =  this.Scene.Bll.Dr_Repair_Lar.GetPCI(plan.Mainsegid);//PCI折减
                        //添加到集合
                        planList.Add(plan);
                    }
                    #endregion
                }
                else
                {
                    #region 未来年份
                    //获取路网决策路段
                    Expression<Func<Dn_Divi_Planning, bool>> exp = null;
                    exp = pre => (pre.Anni_Name == rdnet && pre.Divi_Time==(y-1).ToString());//以预测年的前一年作为基准
                    IEnumerable<Dn_Divi_Planning> enumer = this.Scene.Bll.Dn_Divi_Planning.Get<Dn_Divi_Planning>(exp, null);
                    foreach (Dn_Divi_Planning r in enumer)
                    {
                        string modelPci = "";
                        //预测PCI
                        double PCI = GetCusomPci(r, y, ref modelPci);
                        Dn_Divi_Result result = this.Scene.Bll.Dn_Divi_Result.GetSingle(r.Mainsegid) as Dn_Divi_Result;
                        //根据指标来处理养护类型
                        ProcessSEGID_MAIN(result);

                        //保存到路网决策路段表
                        Dn_Divi_Planning plan = new Dn_Divi_Planning();
                        plan.Id = Guid.NewGuid().ToString(); // id
                        plan.Anni_Name = rdnet;
                        plan.Divi_Time = y.ToString(); //规划年度
                        plan.Mainsegid = r.Mainsegid;//决策路段
                        plan.RoadnetId = rdnet;//路网ID
                        plan.Segid = r.Segid;//基础路段
                        plan.Rdwayid = r.Rdwayid;//路线编号
                        plan.Segid_Main = r.Segid_Main;//养护类型 
                        plan.Beginmp = r.Beginmp;
                        plan.Endmp = r.Endmp;
                        plan.Pqi = r.Pqi;
                        plan.Pci = PCI;
                        plan.Pssi = r.Pssi;
                        plan.Rqi = r.Rqi;
                        plan.Sri = r.Sri;
                        plan.Rl = r.Rl;
                        plan.Modelgroup_Pci = modelPci;//模型组ID
                        plan.Main_Year = y.ToString();//养护年份

                        plan.Segid_Repdefl = r.Segid_Repdefl;
                        plan.Segid_Elamod = r.Segid_Elamod;
                        plan.Segid_Pcidr = r.Segid_Pcidr;
                        

                        //plan.Segid_Repdefl = this.Scene.Bll.Dr_Repair_Mid.GetRepdefl(plan.Mainsegid);//计算弯沉值
                        //plan.Segid_Elamod = this.Scene.Bll.Dr_Repair_Mid.GetELAMOD(plan.Mainsegid);//回弹模量

                        //plan.Segid_Pcidr = this.Scene.Bll.Dr_Repair_Lar.GetPCI(plan.Mainsegid);//PCI折减
                        //添加到集合
                        planList.Add(plan);
                    }
                    #endregion
                }
                if(planList.Count>0)
                {
                    //清除原有的资金分析表
                    this.Scene.Bll.Dn_Divi_Planning.DeleteAll<Dn_Divi_Planning>(rdnet, y.ToString());
                    this.Scene.Bll.Dn_Divi_Planning.SaveAll(planList.ToArray());
                }
                return Ok("ok");
            }
            catch (Exception ex)
            {
                var response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
                {
                    Content = new StringContent(ex.Message),
                    ReasonPhrase = "Server Error"
                };
                throw new HttpResponseException(response);
            }
        }


        /// <summary>
        /// 根据指标修正路段的养护类型
        /// </summary>
        /// <param name="r"></param>
        private void ProcessSEGID_MAIN(Dn_Divi_Result r)
        {
            if (r.Pssi != null) //用pci和pssi同时作为筛选条件
            {
                if (r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R160 || r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R161)  //高速，一级
                {
                    if (r.Pci >= 90) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12000;//日常
                    else if (r.Pssi >= 80 && (r.Pci >= 80 && r.Pci < 90)) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12001;//预防
                    else if (r.Pssi < 80 && (r.Pci >= 80 && r.Pci < 90)) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12002;//中
                    else if (r.Pssi >= 80 && (r.Pci >= 70 && r.Pci < 80)) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12002;//中
                    else if (r.Pssi < 80 && (r.Pci >= 70 && r.Pci < 80)) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12003;//大
                    else if ( r.Pci < 70) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12003;//大
                }
                else  //二级以下
                {
                    if (r.Pci >= 80) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12000;//日常
                    else if (r.Pssi >= 70 && (r.Pci >= 70 && r.Pci < 80)) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12001;//预防
                    else if (r.Pssi < 70 && (r.Pci >= 70 && r.Pci < 80)) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12002;//中
                    else if (r.Pssi >= 70 && (r.Pci >= 60 && r.Pci < 70)) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12002;//中
                    else if (r.Pssi < 70 && (r.Pci >= 60 && r.Pci < 70)) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12003;//大
                    else if (r.Pci < 60) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12003;//大
                }
            }
            else  //只使用PCI
            {
                if (r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R160) //高速
                {
                    if (r.Pci >= 90) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12000;//日常
                    else if (r.Pci >= 80 && r.Pci < 90) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12001;//预防
                    else if (r.Pci >= 70 && r.Pci < 80) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12002;//中修
                    else if (r.Pci < 70) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12003;//大修
                }
                else if (r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R161) //一级
                {
                    if (r.Pci >= 85) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12000;//日常
                    else if (r.Pci >= 75 && r.Pci < 85) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12001;//预防
                    else if (r.Pci >= 65 && r.Pci < 75) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12002;//中修
                    else if (r.Pci < 65) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12003;//大修
                }
                else if (r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R162) //二级
                {
                    if (r.Pci >= 80) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12000;//日常
                    else if (r.Pci >= 70 && r.Pci < 80) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12001;//预防
                    else if (r.Pci >= 60 && r.Pci < 70) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12002;//中修
                    else if (r.Pci < 60) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12003;//大修
                }
                else if (r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R163) //三级
                {
                    if (r.Pci >= 75) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12000;//日常
                    else if (r.Pci >= 65 && r.Pci < 75) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12001;//预防
                    else if (r.Pci >= 55 && r.Pci < 65) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12002;//中修
                    else if (r.Pci < 55) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12003;//大修
                }
                else if (r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R164) //四级
                {
                    if (r.Pci >= 70) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12000;//日常
                    else if (r.Pci >= 60 && r.Pci < 70) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12001;//预防
                    else if (r.Pci >= 50 && r.Pci < 60) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12002;//中修
                    else if (r.Pci < 50) r.Segid_Main = (int)Common.C_Enum.MainTypeEnum.M12003;//大修
                }
            }
            //使用rqi
            if (r.Rqi != null)
            {
                if (r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R160 || r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R161)  //高速，一级
                {
                    if (r.Rqi >= 80)//日常
                    {
                        int rdClass = (int)Common.C_Enum.MainTypeEnum.M12000;
                        if (r.Rdclass_Dictid < rdClass) r.Rdclass_Dictid = rdClass;//级别比它好就修正
                    }
                    else //中修
                    {
                        int rdClass = (int)Common.C_Enum.MainTypeEnum.M12002;
                        if (r.Rdclass_Dictid < rdClass) r.Rdclass_Dictid = rdClass;//级别比它好就修正
                    }
                }
                else //其他等级公路
                {
                    if (r.Rqi >= 70)//日常
                    {
                        int rdClass = (int)Common.C_Enum.MainTypeEnum.M12000;
                        if (r.Rdclass_Dictid < rdClass) r.Rdclass_Dictid = rdClass;//级别比它好就修正
                    }
                    else //中修
                    {
                        int rdClass = (int)Common.C_Enum.MainTypeEnum.M12002;
                        if (r.Rdclass_Dictid < rdClass) r.Rdclass_Dictid = rdClass;//级别比它好就修正
                    }
                }
            }

            //使用SRI
            if (r.Sri != null)
            {
                if (r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R160 || r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R161)  //高速，一级
                {
                    if (r.Sri < 38.89)//中修
                    {
                        int rdClass = (int)Common.C_Enum.MainTypeEnum.M12002;
                        if (r.Rdclass_Dictid < rdClass) r.Rdclass_Dictid = rdClass;//级别比它好就修正
                    }
                }
                else //其他等级公路
                {
                    if (r.Sri < 38.65)//中修
                    {
                        int rdClass = (int)Common.C_Enum.MainTypeEnum.M12002;
                        if (r.Rdclass_Dictid < rdClass) r.Rdclass_Dictid = rdClass;//级别比它好就修正
                    }
                }
            }
            //使用RDI
            if (r.Rdi != null)
            {
                if (r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R160 || r.Rdclass_Dictid == (int)Common.C_Enum.RoadClassEnum.R161)  //高速，一级
                {
                    if (r.Rdi >= 80)//日常
                    {
                        int rdClass = (int)Common.C_Enum.MainTypeEnum.M12000;
                        if (r.Rdclass_Dictid < rdClass) r.Rdclass_Dictid = rdClass;//级别比它好就修正
                    }
                    else //中修
                    {
                        int rdClass = (int)Common.C_Enum.MainTypeEnum.M12002;
                        if (r.Rdclass_Dictid < rdClass) r.Rdclass_Dictid = rdClass;//级别比它好就修正
                    }
                }
                else //其他等级公路
                {
                    if (r.Rdi >= 70)//日常
                    {
                        int rdClass = (int)Common.C_Enum.MainTypeEnum.M12000;
                        if (r.Rdclass_Dictid < rdClass) r.Rdclass_Dictid = rdClass;//级别比它好就修正
                    }
                    else //中修
                    {
                        int rdClass = (int)Common.C_Enum.MainTypeEnum.M12002;
                        if (r.Rdclass_Dictid < rdClass) r.Rdclass_Dictid = rdClass;//级别比它好就修正
                    }
                }
            }
        }

        private double GetCusomPci(Dn_Divi_Planning r, int y, ref string modelPci)
        {
            try
            {
                //获取决策路段对象 
                Dn_Divi_Result result = this.Scene.Bll.Dn_Divi_Result.GetSingle(r.Mainsegid) as Dn_Divi_Result;
                //获取模型
                if (r.Segid_Main == (int)Common.C_Enum.MainTypeEnum.M12000) //日常养护
                {
                    modelPci = result.ModelGroup_PCI;
                    return this.Scene.Bll.Dn_Divi_Result.GetPciByModel(result, y);
                }
                else if (r.Segid_Main == (int)Common.C_Enum.MainTypeEnum.M12001)//预防性养护
                {
                    //查询面层厚度
                    double thick_s = this.Scene.Bll.Dn_Divi_Result.GetThick_S(r.Rdwayid, Convert.ToInt32(result.Direction_Dictid), Convert.ToDouble(r.Beginmp), Convert.ToDouble(r.Endmp));
                    //获取预防性养护措施
                    string yfType = this.Scene.Bll.Dn_Divi_Result.GetMeas_ini(r.Anni_Name, y - 1);
                    //获取模型
                    Dm_Modelgroup model = this.Scene.Bll.Dn_Divi_Result.GetModel<Dm_Modelgroup>(Convert.ToInt32(result.Pvmttype_Dictid), Convert.ToInt32(result.Basictype_Dictid), Convert.ToInt32(r.Segid_Main), yfType, thick_s) as Dm_Modelgroup;
                    modelPci = model.Modelgroup_Id;
                    //获取预测PCI
                    return STHPMS1.BLL.B_Serv.ModelCalculateService.CreateServiceByModel(model).CalculateY(this.Scene.Bll.Dm_Modelgroup.GetEaslByModel(result, y));
                }
                else if (r.Segid_Main == (int)Common.C_Enum.MainTypeEnum.M12002)//中修
                {
                    return this.Scene.Bll.Dn_Divi_Result.GetThick_Mid(r, y, result, ref modelPci);

                }
                else //大修
                {
                    return this.Scene.Bll.Dn_Divi_Result.GetThick_Max(r, y, result, ref modelPci);//大修
                }
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }
    }
}